package de.fhffm.gärtnerei.gui;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.text.MaskFormatter;

import de.fhffm.gärtnerei.exceptions.InputException;
import de.fhffm.gärtnerei.tabellen.Aussaat;
import de.fhffm.gärtnerei.tabellen.Bewaesserung;
import de.fhffm.gärtnerei.tabellen.Ernte;
import de.fhffm.gärtnerei.tabellen.Wachstum;

public class ErnteFenster implements ActionListener {
	
	private double ertrag;
	
	private String datum;
	private String genaueReifezeit;
	private String aussaatDatum;
	private String stueckzahlString;
	private String ertragString;
	
	private int stueckzahl;
	
	private JTextField txtErtrag = new JTextField(8);
	private JTextField txtStueckzahl = new JTextField(8);
	
	private JFormattedTextField txtDatum ;
	
	private JLabel lblErtrag = new JLabel("Ertrag");
	private JLabel lblStueckzahl = new JLabel("Stückzahl");
	private JLabel lblDatum = new JLabel("Datum");
	private JLabel infoLabel = new JLabel();
	
	private JButton btnSpeichern = new JButton("Speichern");
	private JButton btnAbbrechen = new JButton("Abbrechen");
	
	private JPanel eingabePanel = new JPanel(new GridLayout(3,2));
	private JPanel buttonPanel = new JPanel();
	private JPanel infoPanel = new JPanel();

	private JFrame ernteFrame = new JFrame();
	
	private List<String> ausgewaehlteZeile;
	
	private StringBuilder sb = new StringBuilder();
	
	private MaskFormatter datumFormat= null;
	
	private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd.MM.yyyy");
	
	private Date aktuellesDatum = new Date();
	private Date aussaatDate;
	private Date ernteDate = null;
	
	
	ErnteFenster(List<String> ausgewaehlteZeile){
		
		this.ausgewaehlteZeile = ausgewaehlteZeile;
		ernteFrame.setSize(400,500);
		ernteFrame.setLocationRelativeTo(null);
		ernteFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		ernteFrame.setVisible(true);
		ernteFrame.setResizable(true);
		ernteFrame.setLayout(new BorderLayout());
		ernteFrame.setTitle("Aussaat Ernten");
		sb.append("<html>Die Pflanze: '").append(ausgewaehlteZeile.get(2)).append("'");
		sb.append("<br>").append("Aus der Aussaat mit der ID: ").append(ausgewaehlteZeile.get(0)).append(" ernten.<br><br>");
		
		infoLabel.setText(sb.toString());
		sb.setLength(0);
		infoPanel.add(infoLabel);
		
		eingabePanel.add(lblErtrag);
		eingabePanel.add(txtErtrag);
		txtErtrag.setToolTipText("Ertrag der Ernte in gramm");
		eingabePanel.add(lblStueckzahl);
		eingabePanel.add(txtStueckzahl);
		txtStueckzahl.setToolTipText("Anzahl der geernteten Pflanzen");
		eingabePanel.add(lblDatum);
		setzeDatumTxtFeld();
		
		buttonPanel.add(btnSpeichern);
		btnSpeichern.addActionListener(this);
		buttonPanel.add(btnAbbrechen);
		btnAbbrechen.addActionListener(this);
		
		ernteFrame.getContentPane().add(infoPanel, BorderLayout.NORTH);
		ernteFrame.getContentPane().add(eingabePanel,BorderLayout.CENTER);
		ernteFrame.getContentPane().add(buttonPanel,BorderLayout.SOUTH);
		ernteFrame.pack();
		
	}

	private void setzeDatumTxtFeld() {
		
		try {
			datumFormat = new MaskFormatter("##.##.####");
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		txtDatum = new JFormattedTextField(datumFormat);
		txtDatum.setText(simpleDateFormat.format(aktuellesDatum));
		eingabePanel.add(txtDatum);
	}
		
	@Override
	public void actionPerformed(ActionEvent e) {
		
		Object obj = e.getSource();
		
		if (obj == btnAbbrechen) {	
			ernteFrame.dispose();
		}
		
			if(obj == btnSpeichern){

				if(ueberpruefeEingabe()) {
					
					if(istBerechnungMoeglich()){
						
						berechneGenaueReifezeit();
						
						if(doLoescheAussaat()){
							
							fuegeErnteEin();
							einfügenEnde();
						}else{
							System.out.println("Löschen abgebrochen");
						}	
					}else{
						
						System.out.println("Fehler bei der Berechnung!");
					}

				}else{
					System.out.println("Fehler bei der Eingabe");
				}	
			}
	}


	private void einfügenEnde() {
		
		Object[] options = {"Fertig!","Neue Ernte!"};
		int selected = JOptionPane.showOptionDialog(null,"Ernte hinzugefügt!", "Ernten Erfolgreich", JOptionPane.YES_NO_OPTION,
					   JOptionPane.QUESTION_MESSAGE, null , options ,options[1]);
		
		switch(selected){
		case 0:
			ernteFrame.dispose();
			break;
		case 1:
			ernteFrame.dispose();
			new FortschrittTabellenFenster(3);
			break;
		}
	}

	private void fuegeErnteEin() {
		
		int aussaatID = Integer.parseInt(ausgewaehlteZeile.get(0));
		String pflanze = ausgewaehlteZeile.get(2);
		
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("test");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Ernte ernte = new Ernte();
		ernte.setGeernteteAussaatID(aussaatID);
		ernte.setGeerntetepflanze(pflanze);
		ernte.setErtrag(ertragString);
		ernte.setStueckzahl(stueckzahlString);
		ernte.setErnteDatum(datum);
		ernte.setGenaueReifezeit(genaueReifezeit);
		
		em.persist(ernte);
		em.getTransaction().commit();
		em.close();	
	}

	private boolean doLoescheAussaat() {
		
		Object[] options = {"Löschen","Abbrechen"};
		int selected = JOptionPane.showOptionDialog(null,"Wenn Sie eine Aussaat ernten, " +
				       "wird diese samt Fortschritt(Wachstum & Bewässerung) gelöscht!", "ACHTUNG!", JOptionPane.YES_NO_OPTION,
				       JOptionPane.WARNING_MESSAGE, null , options ,options[1]);
		switch(selected){
		case 0: // Löschen
			loescheWachstumBewaesserungAussaat();
			return true;

		case 1://Abbrechen
			System.out.println("Löschen Abgebrochen");
			return false;

	}
	return false;
	}


	private void loescheWachstumBewaesserungAussaat() {
		
		int wachstumID = 0;
		int bewaesserungID = 0;
		int aussaatID = Integer.parseInt(ausgewaehlteZeile.get(0));
		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("test");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();

		Query q = em.createQuery("SELECT a FROM Aussaat a WHERE a.aussaatID =:ID");
		  q.setParameter("ID",aussaatID);
		 
		 Aussaat aussaat = (Aussaat) q.getSingleResult();
		 Wachstum wachstum = aussaat.getWachstum();
		 Bewaesserung bewaesserung = aussaat.getBewaesserung();
		 
		 try{
			 wachstumID = wachstum.getWachstumID();
		 }catch(NullPointerException e){
			 System.out.println("Kein Wachstum vorhanden vorhanden");
		 }
		 try{
			 bewaesserungID = bewaesserung.getBewaesserungID();
		 }catch(NullPointerException e){
			 System.out.println("Keine Bewässerung vorhanden");
		 }
		 
		 q = em.createQuery("DELETE FROM Wachstum w WHERE w.wachstumID =:ID");
		 	 q.setParameter("ID", wachstumID);
		 	 q.executeUpdate();
		 	 
		 	 
		 q = em.createQuery("DELETE FROM Bewaesserung b WHERE b.bewaesserungID =:ID");
		 	q.setParameter("ID",bewaesserungID);
		 	q.executeUpdate();
		 	
		 	
		 q = em.createQuery("DELETE FROM Aussaat a WHERE a.aussaatID =:ID");
		 	q.setParameter("ID", aussaatID);
		 	q.executeUpdate();
		 
		 
	  
		em.getTransaction().commit();
		em.close(); 
		
	}

	private void berechneGenaueReifezeit(){ 
		
			long vergangeneMiliSek = ernteDate.getTime() - aussaatDate.getTime();
			
			/*
			 * Milisekunden / 1000 => Sekunden
			 * Sekunden / 60 => Minuten
			 * Minuten / 60 => Stunden
			 * Stunden / 24 => Tage
			 */
			
			int vergangeneTage = (int) (vergangeneMiliSek/(1000*60*60*24));
			sb.append(vergangeneTage).append(" Tag/e");
			genaueReifezeit = sb.toString();
			
		}

	private boolean istBerechnungMoeglich()  {
		
		hohleAussaatDatum();
		
		try {
			
			aussaatDate = simpleDateFormat.parse(aussaatDatum);
			ernteDate = simpleDateFormat.parse(datum);
		} catch (ParseException e) {
			
			e.printStackTrace();
			return false;
		}
		
		try {
			
			if(aussaatDate.equals(ernteDate)){
				
				throw new InputException("Das Ernte Datum darf nicht gleich dem Datum der Aussaat sein!");
			
			}else if(ernteDate.before(aussaatDate)){
				
				throw new InputException("Das Ernte Datum darf nicht vor dem Aussaat Datum liegen!");
			
			}
			
		}catch(InputException e){
			
			return false;
		}
		
		return true;
	}

	private void hohleAussaatDatum() {
		
		int aussaatID = Integer.parseInt(ausgewaehlteZeile.get(0));

		EntityManagerFactory factory;
		factory = Persistence.createEntityManagerFactory("test");
		EntityManager em = factory.createEntityManager();
		em.getTransaction().begin();
		
		Query q = em.createQuery("SELECT a FROM Aussaat a WHERE a.aussaatID =:ID");
				  q.setParameter("ID",aussaatID);
		Aussaat aussaat = (Aussaat) q.getSingleResult();	
		
		aussaatDatum = aussaat.getAussaatDatum();
		
		em.close();
		
	}


	private boolean ueberpruefeEingabe() {
		
		boolean pruefe = false;
		try {
			ueberpruefeDatum();
			pruefe = hohleEingabe();

		} catch (InputException e) {
			System.out.println("Eingabe Fehler");
		} catch (NumberFormatException n){
			System.out.println("Bitte Zahlen eingeben!");
			JOptionPane.showMessageDialog(null,"Bitte für die Menge nur Zahlen eingeben.","Fehler",JOptionPane.ERROR_MESSAGE);
		}
		return pruefe;
	}

	private boolean hohleEingabe() throws InputException {
		
		ertrag = Double.parseDouble(txtErtrag.getText());
		sb.append(ertrag).append(" gramm");
		ertragString = sb.toString();
		sb.setLength(0);
		stueckzahl = Integer.parseInt(txtStueckzahl.getText());
		sb.append(stueckzahl).append(" Stück");
		stueckzahlString = sb.toString();
		sb.setLength(0);
		
		if(isEingabeLeer()){
			
			throw new InputException("Eine oder mehrere Eingaben fehlen, bitte keine Negativen Zahlen angeben!");
			
		
		}else{

			return true;
		}
	}

	private boolean isEingabeLeer() {
		
		if(ertrag <= 0.0 || stueckzahl <= 0 ){
			
			return true;
		
		}else{
		
			return false;
		}
	}

	private void ueberpruefeDatum() throws InputException {
		
		/*Das Aktuelle Datum wird in einen String mit dem format dd.mm.yyyy umgewandelt.
		Dan wird das aktuelle Datum wieder als Date gespeichert nur mit dem vorher definierten format
		so kann das aktuelle Datum mit dem eingegebenen Datum verglichen werden */
		
		datum = txtDatum.getText();				
		String aktuellesDatumString = simpleDateFormat.format(aktuellesDatum);
		String[] teilString = datum.split(Pattern.quote(".")); // Das eingegebene Datum wird gesplittet
		 
		try {
			 ernteDate = simpleDateFormat.parse(datum);
			 aktuellesDatum = simpleDateFormat.parse(aktuellesDatumString);
			
		} catch (ParseException e) {
			e.printStackTrace();
		}
		
		if(ernteDate.after(aktuellesDatum)){
			throw new InputException("Das eingegebene Datum darf nicht nach dem aktuellem Datum liegen!");
			
		// Eingegebenes Datum ist ungültig wenn kein Tag, Monat oder Jahr angegeben wird bsp.: 00.00.0000	
		// um dies zu überprüfen wird der vorher gesplittete String genutzt
		}else if((teilString[0]).equals("00") || (teilString[1].equals("00") || teilString[2].equals("0000") || teilString[2].substring(0, 1).equals("0")) ){
		    throw new InputException("Das Datum muss im format tt.mm.yyyy eingegeben werden und darf nicht 0 sein");
		
		}else if(ernteDate.equals(aktuellesDatum)){
			System.out.println("Alles ok");
		}
		
	}
}